热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

驼峰|篇幅_JetpackDataStore你总要了解一下吧?

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Jetpack DataStore 你总要了解一下吧?相关的知识,希望对你有一定的参考价值。 目录 一、DataStore 介绍 Preference

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Jetpack DataStore 你总要了解一下吧?相关的知识,希望对你有一定的参考价值。


目录

一、DataStore 介绍

Preferences DataStore 和 Proto DataStore

二、Preferences DataStore

2.1 添加依赖

2.2 使用 Preferences DataStore 存储键值对

2.2.1 创建 DataStore

2.2.1 DataStore 写入数据

2.2.3 DataStore 读取数据

三、Proto DataStore

3.1 定义架构

3.2 创建 Proto DataStore

四、相关链接




一、DataStore 介绍

        DataStore 是 android Jetpack 中的一个组件,它是一个数据存储的解决方案,跟 SharedPreferences 一样,采用key-value形式存储。

        DataStore 保证原子性,一致性,隔离性,持久性。尤其是,它解决了 SharedPreferences API 的设计缺陷。

        Jetpack DataStore 是经过改进的新版数据存储解决方案,旨在取代 SharedPreferences,让应用能够以异步、事务方式存储数据。



注意:DataStore 比较适合小数据和简单操作,并且无法局部的更新数据。如果你需要支持大型或复杂的数据集、部分更新或引用完整性,请考虑使用 Room 而不是 DataStore。



Preferences DataStore 和 Proto DataStore


  • Preferences DataStore:与SharedPreferences类似,通过键值对存储数据,此实现不需要预定义模式,也不提供类型安全。

  • Proto DataStore:通过Protocol-Buffers定义存储数据类型以及结构,保证类型安全。

        本文重点了解Preferences DataStore。


二、Preferences DataStore

        与SharedPreferences类似,通过键值对存储数据,此实现不需要预定义模式,也不提供类型安全。


2.1 添加依赖

        在你项目的app_module对应的build.gradle中添加如下依赖:

dependencies 
    //Typed DataStore (Typed API surface, such as Proto)
    implementation "androidx.datastore:datastore:1.0.0"
//    //可选 - RxJava2 support
//    implementation "androidx.datastore:datastore-rxjava2:1.0.0"
//    //可选 - RxJava3 support
    implementation "androidx.datastore:datastore-rxjava3:1.0.0"
    
    //Preferences DataStore (SharedPreferences like APIs)
    implementation "androidx.datastore:datastore-preferences:1.0.0"
//    // 可选 - RxJava2 support
//    implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0"
//    // 可选 - RxJava3 support
    implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0"

2.2 使用 Preferences DataStore 存储键值对

        首先看看 DataStore 源码,DataStore 是一个接口。

package androidx.datastore.core
import kotlinx.coroutines.flow.Flow
import java.io.IOException
/**
 * DataStore数据存储提供了一种安全、持久的方式来存储少量数据,如 preferences 和应用程序状态。
 * 数据存储提供了ACID保证。它是线程安全的,并且不阻塞。特别是,它解决了SharedReferences API的这些设计缺陷:
 * 1. Synchronous API encourages StrictMode violations
 * 2. apply() and commit() have no mechanism of signalling errors
 * 3. apply() will block the UI thread on fsync()
 * 4. Not durable – it can returns state that is not yet persisted
 * 5. No consistency or transactional semantics
 * 6. Throws runtime exception on parsing errors
 * 7. Exposes mutable references to its internal state
 */
public interface DataStore 
    public val data: Flow
    public suspend fun updateData(transform: suspend (t: T) -> T): T

以上可以看出 DataStore 是基于 协程 和 Flow 实现的。


  • data 是一个 Flow 对象。

  • updateData() 用于更新对象。

        并且查看 DataStore 的其他相关源码你会发现他们都是基于Kotlin语言开发。Google 对于推 Kotlin 那是相当执着。


2.2.1 创建 DataStore


  • 使用 preferencesDataStore(Kotlin) 创建Datastore 的实例。

  • 如果你使用 RxJava,要使用 RxPreferenceDataStoreBuilder。

        必需的 name 参数是 Preferences DataStore 的名称。

        这里我们使用的是RxJava:

        RxDataStore dataStore =
                new RxPreferenceDataStoreBuilder(this, /*name=*/ "datastore_sc").build();
        //创建使用的key
        Preferences.Key nameKey = PreferencesKeys.stringKey("name");
        Preferences.Key ageKey = PreferencesKeys.intKey("age");

        默认路径:/data/data/com.scc.datastorage/files/datastore/datastore_sc.preferences_pb

        这里创建了两个key,分别是 String 类型和 Int 类型。


2.2.1 DataStore 写入数据

    //关于 nameKey 和 ageKey 请看上面代码。
    putString(nameKey, "name-Scc");
    putInteger(ageKey, 25);    
    
    //2022/1/25 功能:存入String类型的数据
    private void putString(Preferences.Key nameKey, String value) 
        dataStore.updateDataAsync(new Function>() 
            @Override
            public Single apply(Preferences preferences) throws Throwable 
                MutablePreferences mutablePreferences = preferences.toMutablePreferences();
                mutablePreferences.set(nameKey, value);
                return Single.just(mutablePreferences);
            
        );
    
    //2022/1/25 功能:存入Integer类型的数据
    private void putInteger(Preferences.Key ageKey, Integer value) 
        dataStore.updateDataAsync(new Function>() 
            @Override
            public Single apply(Preferences preferences) throws Throwable 
                MutablePreferences mutablePreferences = preferences.toMutablePreferences();
                mutablePreferences.set(ageKey, value);
                return Single.just(mutablePreferences);
            
        );
    

        这里写入的两种类型,这样更加仿版理解和你写成自己的工具类,因为使用 DataStore 比较少实践少就不提供工具类了,以免误导大家。


2.2.3 DataStore 读取数据

    getString(nameKey);
    getInteger(ageKey);
    
    //2022/1/25 功能:获取String类型数据
    private void getString(Preferences.Key nameKey) 
        Log.e("DataStore", nameKey.toString());
        Flowable example = dataStore.data().map(new Function() 
            @Override
            public String apply(Preferences preferences) 
                Log.e("DataStore.apply", preferences.get(nameKey));
                return preferences.get(nameKey);
            
        );
        Log.e("DataStore.Flowable", example.first("default").blockingGet());
    
    //2022/1/25 功能:获取Integer类型数据
    private void getInteger(Preferences.Key ageKey) 
        Log.e("DataStoreKey", ageKey.toString());
        Flowable example = dataStore.data().map(new Function() 
            @Override
            public Integer apply(Preferences preferences) 
                Log.e("DataStore.apply", preferences.get(ageKey).intValue() + "");
                return preferences.get(ageKey);
            
        );
        Log.e("DataStore.Flowable", example.first(12).blockingGet().toString());
    


三、Proto DataStore

        通过Protocol-Buffers定义存储数据类型以及结构,保证类型安全。

        Proto DataStore 实现使用 DataStore 和 Protocol-Buffers 将类型化对象持久保存到磁盘。

什么是 Protocol-Buffers?

        Protocol-Buffers是谷歌的语言中立、平台中立、可扩展的机制,用于序列化结构化数据——比如XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码,轻松地在各种数据流之间以及使用各种语言编写和读取结构化数据。


3.1 定义架构

        Proto DataStore 需要app/src/main/proto/目录中的 proto 文件中的预定义模式。此架构定义了您在 Proto DataStore 中持久保存的对象的类型。

syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.scc.datastorage.proto";
option java_outer_classname = "User";
message User
  string name = 1;
  int32 age = 2;

.proto 文件以包声明开头,这有助于防止不同项目之间的命名冲突。


  • java_multiple_files:可以为每个生成的类生成一个单独的 .java 文件。

  • java_package:指定生成的类应该使用什么 Java 包名称。如果您没有明确指定,它只会匹配包声明给出的包名。

  • java_outer_classname:定义了类名。如果没有设置这个 options ,它将通过将文件名转换为大写驼峰式来生成。例如,默认情况下,“my_proto.proto”将使用“MyProto”作为包装类名称。

定义 message:


  • 可以使用许多标准的简单数据类型可用作字段类型,包括 bool、int32、float、double 和 string。

  • 还可以通过使用其他 message 类型作为字段类型来为你的消息添加进一步的结构。

        每个元素上的 "= 1"、"= 2" 标记标识该字段在二进制编码中使用的唯一 "tag"

        更多关于 的内容可以去官网找找 protobuf 语言指南。



注意:存储对象的类是在编译时从 proto 文件中定义的message生成的。确保你 rebuild 你的项目。



3.2 创建 Proto DataStore


  • 1.定义一个实现 Serializer 的类,其中 T 是 proto 文件中定义的类型。

  • 2.使用 dataStore 创建的属性委托来创建 DataStore 的实例,其中 T 是 proto 文件中定义的类型。

        写到这里 proto 文件中定义的类无法生成,也尝试了很多办法,不知道什么情况。后续步骤可参照官网,其他方法和Preferences DataStore类似。就不占用篇幅了。


四、相关链接

官方文档 DataStore

        个人感觉 DataStore 还没有 SP 和 MMKV 好用,推荐使用 MMKV 毕竟上线好几年了,而且是大厂推出,相对稳定一些,有些个人自己实现了 SP 的功能,但是万一有 Bug 或者突然不继续维护了是不是就尴尬了。

 

 


推荐阅读
  • Annotation的大材小用
    为什么80%的码农都做不了架构师?最近在开发一些通用的excel数据导入的功能,由于涉及到导入的模块很多,所以开发了一个比较通用的e ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 基于分布式锁的防止重复请求解决方案
    一、前言关于重复请求,指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同,如查 ... [详细]
  • Android系统启动过程分析一、Android平台架构首先贴一张Android系统架构图方便理解整个Android架构,这可以让我们从整体上对整个启动流程有个大概认知。可以看出整 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 这个问题困扰了我两天,卸载Dr.COM客户端(我们学校上网要装这个客户端登陆服务器,以后只能在网页里输入用户名和密码了),问题解决了。问题的现象:在实验室机台式机上安装openfire和sp ... [详细]
  • 我正在尝试将一些索引和浮点值保存到tfrecords,并使用tf.data ... [详细]
author-avatar
繁華落盡灬熙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有